package org.brisling.medical.queryService;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.brisling.base.domain.ImportExcelDomain;
import org.brisling.base.domain.ListDomain;
import org.brisling.base.domain.RetDomain;
import org.brisling.base.service.AbstractBaseQueryService;
import org.brisling.common.ConstSysParam;
import org.brisling.common.util.ReflectDataUtil;
import org.brisling.common.util.WhereUtil;
import org.brisling.medical.domain.MedicalPathwayPatient;
import org.brisling.medical.domain.MedicalPathwayPatientConclusion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
@RequestMapping("/pathwayPatient/query")
public class QueryMedicalPathwayPatient extends AbstractBaseQueryService<MedicalPathwayPatient>{
	

	final private int tableString = 0;
	final private int tableDouble = 1;
	final private int tableInt = 2;
	final private int tableDoubleString = 3;
	
	public QueryMedicalPathwayPatient(){
		this.moduleName = ConstSysParam.MODULE_PATHWAY_PATIENT;
		this.subSystem = ConstSysParam.SUBSYSTEM_MEDICAL;
		this.tableName = this.moduleName;
		this.clazz = MedicalPathwayPatient.class;
		typeMap = this.getTypeMap(clazz);
	
	}
	
	@PersistenceContext(unitName=ConstSysParam.SUBSYSTEM_SYSMAN)
	@Autowired
	protected void setEntityManager(EntityManager entityManager){
		this.entityManager = entityManager;		
	}
	
	@RequestMapping("/mainPage.action")
	public ModelAndView getMainPage(){
		return getBizMainPage();
	}
	
	/* (non-Javadoc)
	 * @see org.brisling.service.sysman.DepartmentServiceInf#getEditPage()
	 */
	@RequestMapping("/editPage.action")
	public ModelAndView getEditPage(){
		return getBizEditPage();
	}
	
	@RequestMapping("/getListDomain.action")
	public ListDomain<MedicalPathwayPatient> getListDomain(@RequestBody(required=false) String body){		
		
		return super.getListDomainByConditionAndOrder(body, typeMap, orderMap, true);
		
	}
	
	@RequestMapping("/getList.action")
	public List<MedicalPathwayPatient> getList(@RequestParam(value="page",required=false) Integer page,
			@RequestParam(value="rows",required=false) Integer rows,
			@RequestParam(value="deptid",required=false) Integer deptid,
			@RequestParam(value="sort",required=false) String sort){		
		
		StringBuilder sb = new StringBuilder();
		String sql = "";
		if(deptid!=null){
			String whereCorse=String.format(sb.append("\"deptid\" = %1$d").toString(),deptid);
			sql = String.format(this.TW_SQL, this.tableName,whereCorse);
		}else{
			sql = String.format(this.T_SQL, this.tableName);
		}
		
		return super.getPagedList(page,rows,sql);
	}
	
	public List<MedicalPathwayPatient> getListAll(Map<String, String> map){	
		
		String sql = "";
		String whereCorse = null;					
			
		whereCorse = WhereUtil.getConditionWhereCorse(map,typeMap);
		System.out.println("whereCorse: " +whereCorse);		
		
		if(whereCorse!=null){			
			sql = String.format(this.TW_SQL, this.tableName,whereCorse);
			return super.getAllList(sql);
		}
		return new ArrayList<MedicalPathwayPatient>();		
		
	}
	/**
	 * 根据指标id查找指标信息
	 * @param id	指标id
	 * @return 指标信息记录 
	 */
	@RequestMapping("/getOne.action")
	public MedicalPathwayPatient getOne(@RequestParam(value="id",required=false) Long id){
		return super.getOne(id);
	}
	
	/**
	 * 根据指标唯一编码查找指标信息
	 * @param identify	指标唯一编码
	 * @return 指标信息记录
	 */
	@RequestMapping("/getOneByIdentify.action")
	public MedicalPathwayPatient getOneByIdentify(@RequestParam(value="identify",required=false) String identify){	
		return super.getOneByIdentify(identify);
	}	
	
	
	@RequestMapping("/getListByField.action")
	public List<MedicalPathwayPatient> getListByField(@RequestParam(value="field",required=false) String field,@RequestParam(value="fieldVal",required=false) String fieldVal){	
		return super.getListByIdentify(field,fieldVal);
	}
	
	/**
	 * 本函数只是单纯的将excel转换成一个能用的二维String数组， 其他的什么都不干
	 */
	@SuppressWarnings("deprecation")
	private String[][] excelToArray(FileInputStream path) throws Exception, IOException {
		// TODO Auto-generated method stub
		POIFSFileSystem fs=new POIFSFileSystem(path);
		//得到Excel工作簿对象
		HSSFWorkbook wb = new HSSFWorkbook(fs);
		//得到Excel工作表对象
		HSSFSheet sheet = wb.getSheetAt(0);
		//得到Excel工作表的行
		HSSFRow row = sheet.getRow(0);
		//得到Excel工作表指定行的单元格
		HSSFCell cell =  row.getCell(0);
		String temp;
		String excelDocSave[][] = new String[sheet.getPhysicalNumberOfRows()][];
		for(int i = 0; i < sheet.getPhysicalNumberOfRows(); i++){
			row = sheet.getRow(i);
			if(row == null){
				break;
			}
			temp = "";
			System.out.println("&&&");
			System.out.println("###" + row.getPhysicalNumberOfCells() + "###");
			excelDocSave[i] = new String[row.getPhysicalNumberOfCells()];
			System.out.println("ttt");
			for(int j = 0; j < row.getPhysicalNumberOfCells(); j++){
				temp = "";
				cell = row.getCell(j);
				if(cell == null){
					continue;
				}
				
				int ctp = cell.getCellType();
				switch(ctp){
				case HSSFCell.CELL_TYPE_NUMERIC:
					double tep = cell.getNumericCellValue();
					temp = "" + tep;
					break;
				case HSSFCell.CELL_TYPE_STRING:
					String teep = cell.getStringCellValue();
					temp = "" + teep;
					break;
				case HSSFCell.CELL_TYPE_BLANK:
					break;
				}
				temp = StringUtils.normalizeSpace(temp);
				temp = StringUtils.deleteWhitespace(temp);
				excelDocSave[i][j] = temp;
			}
		}
		return excelDocSave;
	}
	
	/**
	 * 导入excel
	 * @throws Exception 
	 * @throws IOException 
	 */
	public RetDomain readExcelData(FileInputStream path){
		
		String[][] excelDataArr = null;
		try {
			excelDataArr = excelToArray(path);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return RetDomain.errorDomain("Error when loading file!");
		}
//		printStringDArray(excelDataArr);
		int index = findFstStar(excelDataArr);
		if(index == -1){
			return null;
		}
		@SuppressWarnings("rawtypes")
		HashMap concTitle = makeRealMapIndex(excelDataArr, index, index, excelDataArr[index].length);
		List<ImportExcelDomain> eColList = getExcelColRules();
		RetDomain retMsg = trySaveToMapCol(eColList, concTitle, excelDataArr, index + 1);
		if(retMsg.getStatus().equals("error")){
			return retMsg;
		}
		String diseaseId = (String) retMsg.getRows();
		index = findSecStar(excelDataArr);
		int len = excelDataArr[index + 1].length;
		if(excelDataArr[index + 2].length > len){
			len = excelDataArr[index + 2].length;
		}
		
		return readInformation(excelDataArr, index, len, diseaseId);
//		return mppList;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private RetDomain readInformation(String[][] excelDataArr, int index, int len, String diseaseId) {
		// TODO Auto-generated method stub
		List<ImportExcelDomain> eList = getExcelRules();

		
		HashMap titleMap = makeRealMapIndex(excelDataArr, index++, index++, len);
		int cu = 0;
		List<MedicalPathwayPatient> mppList = new ArrayList<MedicalPathwayPatient>();
		HashMap<String, Object> map = new HashMap<String, Object>();
		while(index < excelDataArr.length){
			for(int i = 0; i < eList.size(); i++){
				String id = eList.get(i).getColName();
				if(!titleMap.containsKey(id)){
					System.out.println("bad boy");
				}
				if(titleMap.containsKey(id)){
					int idLocation = (int)titleMap.get(id);
					String midTemp = "";
					midTemp = excelDataArr[index][idLocation];
					System.out.println("got info " + midTemp + " at location " + idLocation + " by this id: " + id);
					if(midTemp == null|| midTemp.equals("")){
						continue;
					}
					RetDomain rd = colSwitch(map, eList, midTemp, index, i);
					if(rd.getStatus().equals("error")){
						return rd;
					}
					else{
						map = (HashMap) rd.getRows();
					}
				}
			}
			
			MedicalPathwayPatient mpp = new MedicalPathwayPatient();
			map.put("disease_name", diseaseId);
			mpp = (MedicalPathwayPatient) ReflectDataUtil.setData2Obj(mpp, map);
			mppList.add(mpp);
			map.clear();
			index++;
			cu++;
		}
		RetDomain ret = RetDomain.successDomain("");
		ret.setRows(mppList);
		return ret;
	}

	
	
	@SuppressWarnings("rawtypes")
	private RetDomain trySaveToMapCol(List<ImportExcelDomain> eList, HashMap titleMap, String[][] excelDataArr, int index){
		
		HashMap map = new HashMap();
		String ter = null;
		for(int i = 0; i < eList.size(); i++){
			String id = eList.get(i).getColName();
			if(!titleMap.containsKey(id)){
				System.out.println("bad boy");
			}
			
			if(titleMap.containsKey(id)){
				String midTemp = excelDataArr[index][(int)titleMap.get(id)];
				if(id.equals("疾病名称")){
					ter = midTemp;
				}
				if(midTemp == null|| midTemp.equals("")){
					continue;
				}
				RetDomain rd = colSwitch(map, eList, midTemp, index, i);
				if(rd.getStatus().equals("error")){
					return rd;
				}
				else{
					map = (HashMap) rd.getRows();
				}
				System.out.print(excelDataArr[index][i] + '\t');
			}
			
		}
		MedicalPathwayPatientConclusion mpp = new MedicalPathwayPatientConclusion();
		mpp = (MedicalPathwayPatientConclusion) ReflectDataUtil.setData2Obj(mpp, map);
		//save mpp
//		medicalPathPatientConclusionSer.save(mpp);
		map.clear();
		return RetDomain.successDomain(ter);
	}
	
	@SuppressWarnings("unchecked")
	private RetDomain colSwitch(@SuppressWarnings("rawtypes") HashMap map, List<ImportExcelDomain> eList, String midTemp, int index, int i) {
		try {
			switch(eList.get(i).getColType()){
			case tableInt:
				double ansTmp = Double.valueOf(midTemp);
				Long ansInt = (long)ansTmp;
				map.put(eList.get(i).getColCode(), ansInt);
				break;
			case tableString:
				Long ansIntOfString;
				String ansString;
				if(hasDigit(midTemp)){
					double god = Double.valueOf(midTemp);
					ansIntOfString = (long)god;
					ansString = String.valueOf(ansIntOfString);
				}
				else
				{
					ansString = midTemp;
				}
				map.put(eList.get(i).getColCode(), ansString);
				break;
			case tableDouble:
				Double ansDouble = Double.valueOf(midTemp);
				map.put(eList.get(i).getColCode(), ansDouble);
				break;
			case tableDoubleString:
				Double ansDoubleStrDou = Double.valueOf(midTemp);
				String ansDoubleString = ansDoubleStrDou.toString();
				map.put(eList.get(i).getColCode(), ansDoubleString);
				break;
			}
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			return RetDomain.errorDomain("第" + index + "行第" + i + "列发现错误， 请更正后再上传，请勿增加列或留空");
		}
		RetDomain ret = RetDomain.successDomain("");
		ret.setRows(map);
		return ret;
	}


	private List<ImportExcelDomain> getExcelColRules() {
		// TODO Auto-generated method stub
		List<ImportExcelDomain> eList = new ArrayList<ImportExcelDomain>();
		String[] title = {"disease_name", "variationAmount", "accessAmount", "accessPer", "completeAmount", "completePer","variationPer", "hospitalizationAverageDay", "backToHospitalizationAmount", "backToHospitalizationPer", "againSurgeryAmount", "againSurgeryPer", "complicationAmount", "cureAmount", "curePer"};
		String[] cTitl = {"疾病名称", "符合入径标准总例数", "入径总例数", "入组率%", "完成总例数", "完成率%", "变异率%", "平均住院日（天）", "30日内再入院例数", "30日内再入院率%", "再手术总数", "再手术率%", "并发症总数", "治愈总数", "治愈率%"};
		int [] type = {tableString, tableInt, tableInt, tableDouble, tableInt, tableDouble, tableDouble, tableDouble, tableInt, tableDouble, tableInt, tableDouble, tableInt, tableInt, tableDouble};
		for(int i = 0; i < title.length; i++){
			ImportExcelDomain tp = new ImportExcelDomain();
			tp.setColCode(title[i]);
			tp.setColName(cTitl[i]);
			tp.setColType(type[i]);
			tp.setStartLocation(0);
			eList.add(tp);
		}
		
		return eList;
	}

	private int findFstStar(String[][] excelDataArr) {
		// TODO Auto-generated method stub
		for(int i = 0; i < excelDataArr.length; i++){
			if(excelDataArr[i][0].equals("疾病名称")){
				return i;
			}
		}
		return -1;
	}


	private int findSecStar(String[][] excelDataArr) {
		// TODO Auto-generated method stub
		for(int i = 0; i < excelDataArr.length; i++){
			if(excelDataArr[i][0].equals("入径病例登记表")){
				return i + 1;
			}
		}
		return 0;
	}
	
	/*
	 * 本函数产生初始化配置文件
	 */
	List<ImportExcelDomain> getExcelRules(){
		List<ImportExcelDomain> eList = new ArrayList<ImportExcelDomain>();
		String[] title = {"paient_id", "patient_name", "inpatientDate", "hospitalization_day", "before_day", "finish_status","turbiCure", "turbiTurnBetter", "turbiDied", "hospital_infection", "surgery_infection", "hospitalized14", "hospitalized30", "unplanned_surgery", "complication", "variation", "doctor"};
		String[] cTitl = {"住院号", "患者姓名", "入院日期", "住院天数", "术前住院天数", "是否完成（1\\0)", "治愈", "好转", "死亡", "医院感染（1\\0)", "手术部位感染（1\\0)", "14日再住院（1\\0)", "30日再住院（1\\0)", "非计划重返手术（1\\0)", "并发症（1\\0)", "是否变异（1\\0)", "管床医师"};
		int [] type = {tableString, tableString, tableDoubleString, tableInt, tableInt, tableString, tableString, tableString, tableString, tableString, tableString, tableString, tableString, tableString, tableString, tableString, tableString};
		for(int i = 0; i < title.length; i++){
			ImportExcelDomain tp = new ImportExcelDomain();
			tp.setColCode(title[i]);
			tp.setColName(cTitl[i]);
			tp.setColType(type[i]);
			tp.setStartLocation(0);
			eList.add(tp);
		}
		
		return eList;
	}

	//getRules
	//makeRulesMap
	//makeRealStringArr
	//readExcel()
	
	@SuppressWarnings("unchecked")
	public HashMap<Object, Object> makeRulesMap(List<ImportExcelDomain> pramList){
		@SuppressWarnings("rawtypes")
		HashMap map = new HashMap<>();
		for(int i = 0; i < pramList.size(); i++){
			map.put(pramList.get(i).getColName(), i);
		}
		
		return map;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public HashMap makeRealMapIndex(String[][] inArr, int st, int en, int len){
		
		HashMap ans = new HashMap();
		for(int i = st; i <= en; i++){
			for(int j= 0; j < inArr[i].length; j++){
				if(!inArr[i][j].equals("")){
					ans.put(inArr[i][j], j);
				}
			}
		}
		return ans;
	}
	
	public String[] makeRealStringArr(HSSFSheet wb, int st, int en, int len){
		String[] ans = new String[len];
		for(int i = st; i <= en; i++){
			HSSFRow row = wb.getRow(i);
			for(int j= 0; j < len; j++){
				HSSFCell cell = row.getCell(j);
				if(cell.getStringCellValue() != null && (!cell.getStringCellValue().equals(""))){
					ans[j] = cell.getStringCellValue();
				}
			}
		}
		for(int i = 0; i < len; i++){
			ans[i] = StringUtils.normalizeSpace(ans[i]);
			ans[i] = StringUtils.deleteWhitespace(ans[i]);
		}
		return ans;
	}

	public boolean hasDigit(String content) {

		boolean flag = false;
		Pattern p = Pattern.compile(".*\\d+.*");
		Matcher m = p.matcher(content);
		if (m.matches()){
			flag = true;
		}
		return flag;
	}
}
